/* =========================================================================
 * Copyright (c) 2006 and onwards, Josh Glover <jmglov@jmglov.net>,
 * Robert Ota Dieterich <otanobunaga@gmail.com>
 *
 * LICENCE:
 *
 *   This file is distributed under the terms of the BSD-2 License.
 *   See the COPYING file, which should have been distributed with
 *   this file, for details. If you did not receive the COPYING file,
 *   see:
 *
 *   http://www.jmglov.net/opensource/licenses/bsd.txt
 */

#include "SDL_gfxPrimitives.h"

#include "Missile.h"

bool Missile::draw(const SDL_Surface* pSurface) const {
  // If the missile is destroyed, draw nothing
  if (isDestroyed()) return true;

  // If we are not exploding, a normal draw() will suffice
  if (m_explosionRadius == 0) {
    return MobileSprite::draw(pSurface);
  } // if (not exploding)

  // Otherwise, draw the explosion!
  else {
    if (filledCircleRGBA(const_cast<SDL_Surface*>(pSurface),
                         getX(), getY(), m_explosionRadius,
                         m_unmappedColour.r, m_unmappedColour.g,
                         m_unmappedColour.b, 255)
        == 1) {
      return false;
    } // if (circleColor() failed)
  } // else (exploding)

  return true;
} // Missile::draw()

void Missile::explode(void) {
  // If the missile is destroyed, do nothing
  if (isDestroyed()) return;

  m_explosionRadius++;

  // If the missile has just been told to explode, stop it (exploding missiles
  // should not move)
  if (m_explosionRadius == 1) {
    setSpeed(0);
  } // if (missile is done exploding)

  // If missile is done exploding, destroy ourselves and our target
  if (m_explosionRadius > MAX_EXPLOSION_RADIUS) {
    m_explosionRadius = 0;
    destroy();
    m_pTarget->destroy();
    m_pTarget = NULL;
  } // if (missile is done exploding)
} // Missile::explode()

void Missile::move(void) {
  // Let our parent class's move() handle the actual movement
  MobileSprite::move();

  Sint16 x = getX();
  Sint16 y = getY();
  Uint16 w = getW();
  Uint16 h = getH();

  // If we have a target, and it is not destroyed, check for collisions
  if (m_pTarget && !m_pTarget->isDestroyed()) {

    Sint16 tx = m_pTarget->getX();
    Sint16 ty = m_pTarget->getY();
    Uint16 tw = m_pTarget->getW();
    Uint16 th = m_pTarget->getH();

    if ((x + w >= tx && x <= tx + tw && y + h >= ty && y <= ty + th) ||
        (m_lastX + w >= tx && m_lastX <= tx + tw && y + h >= ty)) {
      explode();

      // Return, so we are not destroyed if we have already moved off the screen
      return;
    } // if (collision!)
  } // if (checking for collisions)

  // If we have moved off the screen, self-destruct
  if (x < m_minX || x > m_maxX || y < m_minY || y > m_maxY) {
    destroy();
  } // if (we have moved off the screen)
} // Missile::move()
